/*****************************
 * AdamsAleAppFrame.cpp
 *****************************/

#include "AdamsAleAppFrame.h"

AdamsAleAppFrame::AdamsAleAppFrame( wxWindow* parent ) : MyFrame1( parent ) { }

void AdamsAleAppFrame::OnDClick( wxIdleEvent& event ) {
	if(m_plotCtrl1->getRange() >=0 && m_plotCtrl1->getSill() >= 0) {
		WriteRange( m_plotCtrl1->getRange() );
		WriteSill( m_plotCtrl1->getSill() );
	}
}
void AdamsAleAppFrame::OnToolClicked(wxCommandEvent& event) {
	switch (event.GetId()) {
		case ID_FILENEW:
			OnNew(event);
			break;
		case ID_OPEN:
			OnOpenFile(event);
			break;
		case ID_SAVE:
			OnSave(event);
			break;
	}
}
void AdamsAleAppFrame::OnNew( wxCommandEvent& event ) {
	data = new GeoData;
	int j, i;
	NewDialog dialog(this, wxID_ANY, wxT("New Model"));
	dialog.setName(wxT("ProjectName"));
	dialog.setNumX(50);
	dialog.setNumY(50);
	dialog.setSizeX(1);
	dialog.setSizeY(1);
	if(dialog.ShowModal() == wxID_OK) {
		project = dialog.getName();
		data->SetArea(dialog.getNumX(), dialog.getNumY());
		data->SetDimensions(dialog.getSizeX(), dialog.getSizeY());
		SetTitle(project);
		project += wxT(".aaa");
		SetStatusText(wxT("New project ") + project + wxT(" created"));
		ResetPlot();
		ResizeTable();
		for(j = 0; j< data->GetYSize(); j++) {
			for(i = 0; i < data->GetXSize(); i++) {
				data->SetUnknownPoint(i, j);
			}
		}
	}
}
void AdamsAleAppFrame::OnOpenFile( wxCommandEvent& event ) {
	data = new GeoData;
	static const wxChar *FILETYPES = _T( "Adam's Ale App Model|*.aaa|" );
	wxFileDialog* openFileDialog = new wxFileDialog( this, _("Open file"), wxT(""), wxT(""),
			FILETYPES, wxOPEN, wxDefaultPosition);
	if( openFileDialog->ShowModal() == wxID_OK ) {
		project = openFileDialog->GetFilename();
		SetTitle(project.BeforeLast('.'));
		ResetPlot();
		ReadFile();
		SetStatusText(project+wxT(" opened"));
	}
	openFileDialog->Destroy();
}
void AdamsAleAppFrame::OnSave( wxCommandEvent& event ) {
	SaveFile();
	SetStatusText(project+wxT(" saved"));
}
void AdamsAleAppFrame::OnSaveAs( wxCommandEvent& event ) {
	static const wxChar *FILETYPES = _T("Adam'sAleAppModel|*.aaa|");
	wxFileDialog* saveAsDialog = new wxFileDialog(this, _("Save file as..."), wxT(""),
			project.BeforeLast('.')+wxT(".aaa"), FILETYPES, wxSAVE | wxOVERWRITE_PROMPT, wxDefaultPosition);
	if( saveAsDialog->ShowModal() == wxID_OK ) {
		project = saveAsDialog->GetFilename();
		SetTitle(project.BeforeLast('.'));
		SaveFile();
		SetStatusText(project+wxT(" saved"));
	}
	saveAsDialog->Destroy();
}
void AdamsAleAppFrame::OnImport( wxCommandEvent& event ) {
	data = new GeoData;
	static const wxChar *FILETYPES = _T( "Formatted bore hole data|*.csv|" );
	wxFileDialog* openFileDialog = new wxFileDialog( this, _("Open file"), wxT(""), wxT(""),
			FILETYPES, wxOPEN, wxDefaultPosition);
	if( openFileDialog->ShowModal() == wxID_OK ) {
		project = openFileDialog->GetFilename();
		SetTitle(project.BeforeLast('.'));
		ResetPlot();
		ReadImport();
		SetStatusText(project+wxT(" imported"));
	}
	openFileDialog->Destroy();
}
void AdamsAleAppFrame::OnQuit( wxCommandEvent& event ) { Close(true); }
void AdamsAleAppFrame::OnKrigePoints( wxCommandEvent& event ) {
	int i, size, index;
	double xscale, yscale;

    wxWindowDisabler disableAll;
    wxBusyInfo wait(wxT("Calculating, please wait..."));

	m_textCtrl5->GetValue().ToDouble(&xscale);
	m_textCtrl6->GetValue().ToDouble(&yscale);
	data->SetVariogram(m_listBox1->GetSelection());
	data->SetKnee(m_plotCtrl1->getRange(), m_plotCtrl1->getSill());
	data->SetScale(xscale/100, yscale/100);
	data->SetInterpolation(m_listBox11->GetSelection());

	if(m_checkBox1->IsChecked())
		data->InterpolateSparsePoints(wxAtoi(textCtrlRuns->GetValue()));
	else
		data->InterpolatePoints(wxAtoi(textCtrlRuns->GetValue()));

	vector <GeoData::Unknown> unknowns = data->GetUnknowns();
	size = unknowns.size();
	for(i = 0; i < size; i++) {
		index = unknowns.at(i).Index;
		m_grid1->SetCellValue(data->GetPoint(index).getY(), data->GetPoint(index).getX(),
				wxString::Format(wxT("%f"), data->GetValue(index)));
	}
	SetStatusText(wxT("Calculated values set"));
	m_panel2->SetDataPointer(data, data->GetXSize(), data->GetYSize());
}
void AdamsAleAppFrame::OnAbout( wxCommandEvent& event ) {
	MyDialog2 dialog(this, wxID_ANY, wxT("About..."));
	dialog.ShowModal();
}
/* Plotting Menu Events */
void AdamsAleAppFrame::OnSemivariogram( wxCommandEvent& event ) { plotSemivariogram(); }
void AdamsAleAppFrame::OnResizePlot( wxCommandEvent& event ) {
	m_plotCtrl1->SetViewRect(m_plotCtrl1->GetCurveBoundingRect());
}
void AdamsAleAppFrame::OnPlot( wxCommandEvent& event ) {
	wxRect2DDouble temp = m_plotCtrl1->GetViewRect();
	m_plotCtrl1->DeleteCurve(-1, false);
	m_plotCtrl1->RedrawData();
	if(m_listBox1->GetSelection()==0) {
		m_plotCtrl1->plotModel1();
	}
	if(m_listBox1->GetSelection()==1) {
		m_plotCtrl1->plotModel2();
	}
	if(m_listBox1->GetSelection()==2){
		m_plotCtrl1->plotModel3();
	}
	m_plotCtrl1->SetViewRect(temp);
}
void AdamsAleAppFrame::OnClearPlot( wxCommandEvent& event ) { ResetPlot(); }
void AdamsAleAppFrame::ReadFile() {
	wxTextFile file;
	int j, i;
	double value, test, x, y, deltax, deltay;
	file.Open(project);
    file.GetFirstLine().ToDouble(&x);
    file.GetNextLine().ToDouble(&y);
	file.GetNextLine().ToDouble(&deltax);
	file.GetNextLine().ToDouble(&deltay);
	data->SetArea((int) x, (int) y);
	data->SetDimensions(deltax, deltay);
	ResizeTable();
	for(j = 0; j < data->GetYSize(); j++) {
		for(i = 0; i < data->GetXSize(); i++) {
			file.GetNextLine().ToDouble(&test);
			if(test) {
				file.GetNextLine().ToDouble(&value);
				data->SetPoint(i, j, value);
				m_grid1->SetCellValue(j, i, wxString::Format(wxT("%f"), value));
			}
			else
				data->SetUnknownPoint(i, j);
		}
	}
	file.Close();
}
void AdamsAleAppFrame::SaveFile() {
	wxTextFile file;
	int j, i;
	if(!file.Create(project)) {
		file.Open(project);
		file.Clear();
	}
	file.AddLine(wxString::Format(wxT("%d"), data->GetXSize()));
	file.AddLine(wxString::Format(wxT("%d"), data->GetYSize()));
	file.AddLine(wxString::Format(wxT("%f"), data->GetXScale()));
	file.AddLine(wxString::Format(wxT("%f"), data->GetYScale()));
	for(j = 0; j < data->GetYSize(); j++) {
		for(i = 0; i < data->GetXSize(); i++) {
			if(data->GetPoint((data->GetXSize()*j)+i).IsKnown()) {
				file.AddLine(wxT("1"));
				file.AddLine(wxString::Format(wxT("%f"), data->GetValue((data->GetXSize()*j)+i)));
			}
			else
				file.AddLine(wxT("0"));
		}
	}
	file.Write();
	file.Close();
}
/*void AdamsAleAppFrame::SaveFile() {
	wxFile file;
	wxString str = wxT("");
	int j, i;
	file.Create(project, true);
	if(file.IsOpened()) {
		str += wxString::Format(wxT("%d,%d,%lf,%lf\n"), data->GetXSize(), data->GetYSize(),
				data->GetXScale(), data->GetYScale());
		str += wxString::Format(wxT("%lf,%lf,%d,%lf,%lf\n"), data->GetRange(), data->GetSill(),
				m_listBox1->GetSelection(), data->GetXScale(), data->GetYScale());
		str += wxString::Format(wxT("%d,%d\n"), m_listBox11->GetSelection(), wxAtoi(textCtrlRuns->GetValue()));
		for(j = 0; j < data->GetYSize(); j++) {
			for(i = 0; i < data->GetXSize(); i++) {
				if(data->GetPoint((data->GetXSize()*j)+i).IsKnown()) {
					file.AddLine(wxT("1"));
					file.AddLine(wxString::Format(wxT("%f"), data->GetValue((data->GetXSize()*j)+i)));
				}
				else
					str += wxT("0");
			}
		}
		file.Write(str);
		file.Close();
	}
}*/
void AdamsAleAppFrame::ReadImport() {
	wxTextFile file;
	wxString temp;
	int j, i;
	double value;
	double x, y;
	if(file.Open(project)) {
		wxStringTokenizer tkz(file.GetFirstLine(), wxT(","));
		tkz.GetNextToken().ToDouble(&x);
		tkz.GetNextToken().ToDouble(&y);
		data->SetArea((int) x, (int) y);
		tkz.GetNextToken().ToDouble(&x);
		tkz.GetNextToken().ToDouble(&y);
		data->SetDimensions(x, y);
		ResizeTable();
		for(j = 0; j < data->GetYSize(); j++) {
			tkz.SetString(file.GetNextLine(), wxT(","));
			temp = tkz.GetNextToken();
			if(temp.CompareTo(wxT("")) != 0) {
				temp.ToDouble(&value);
				data->SetPoint(0, j, value);
				m_grid1->SetCellValue(j, 0, wxString::Format(wxT("%f"), value));
			}
			else
				data->SetUnknownPoint(0, j);
			temp = tkz.GetNextToken();
			if(temp.CompareTo(wxT("")) != 0) {
				temp.ToDouble(&value);
				data->SetPoint(data->GetXSize()-1, j, value);
				m_grid1->SetCellValue(j, data->GetXSize()-1, wxString::Format(wxT("%f"), value));

			}
			else
				data->SetUnknownPoint(data->GetXSize()-1, j);

		}
		for(j = 0; j < data->GetYSize(); j++) {
			for(i = 1; i < data->GetXSize()-1; i++) {
				data->SetUnknownPoint(i, j);
			}
		}
		file.Close();
	}
}
void AdamsAleAppFrame::ResetPlot() {
	m_plotCtrl1->DeleteCurve(-1, true);
	m_plotCtrl1->ClearPoint();
	m_statusBar1->SetStatusText(wxT("Plot Cleared"));
}
void AdamsAleAppFrame::ResizeTable() {
	if(data->GetYSize() > m_grid1->GetNumberRows())
		m_grid1->AppendRows(data->GetYSize() - m_grid1->GetNumberRows());
	else
		m_grid1->DeleteRows(0, m_grid1->GetNumberRows() - data->GetYSize());
	if(data->GetXSize() > m_grid1->GetNumberCols())
		m_grid1->AppendCols(data->GetXSize() - m_grid1->GetNumberCols());
	else
		m_grid1->DeleteCols(0, m_grid1->GetNumberCols() - data->GetXSize());
	m_grid1->ClearGrid();
}
void AdamsAleAppFrame::plotSemivariogram() {
	double *xsemis, *ysemis;
	if(data == NULL)
		return;
	ysemis = new double[data->GetYSize()];
	xsemis = new double[data->GetXSize()];
	data->ExperimentalSemivariogram(xsemis, ysemis);
	m_plotCtrl1->plotData(xsemis, ysemis, data->GetXSize(), data->GetYSize(), data->GetDeltaX(), data->GetDeltaY());
	m_statusBar1->SetStatusText(wxT("Semivariogram plotted"));
}
